<?php

namespace app\api\middleware;

use app\api\library\Token;
use ReflectionClass;
use support\utils\Tools;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;

class AuthCheckNoLoginActionMiddleware implements MiddlewareInterface
{
    /**
     * 处理请求
     * @param Request $request
     * @param callable $handler
     * @return Response
     */
    public function process(Request $request, callable $handler): Response
    {
        try {
            // 记录请求开始时间
            $request->req_time = microtime(true);
            
            // 获取当前用户token
            $token = $request->header('token');
            $tokenData = Token::get($token);
            
            // 如果已登录，直接通过
            if (!empty($tokenData)) {
                return $handler($request);
            }
            
            // 检查是否需要登录
            if ($this->checkNoNeedLogin($request)) {
                return $handler($request);
            }
            
            // 需要登录但未登录
            return $this->fail('用户信息读取失败,请重新登录', null, 403);
            
        } catch (\Throwable $e) {
            // 记录错误日志
            error_log("Auth Check Error: " . $e->getMessage());
            return $this->fail('系统错误，请稍后重试', null, 500);
        }
    }
    
    /**
     * 检查是否不需要登录
     * @param Request $request
     * @return bool
     */
    protected function checkNoNeedLogin(Request $request): bool
    {
        try {
            // 通过反射获取控制器
            $controller = new ReflectionClass($request->controller);
            $noNeedLogin = $controller->getDefaultProperties()['noNeedLogin'] ?? [];
            
            // 检查是否在免登录列表中
            return !empty($noNeedLogin) && 
                   ($noNeedLogin[0] === '*' || in_array($request->action, $noNeedLogin));
                   
        } catch (\ReflectionException $e) {
            error_log("Reflection Error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * 返回失败响应
     * @param string $msg 错误信息
     * @param mixed $data 返回数据
     * @param int $code 错误码
     * @return Response
     */
    protected function fail($msg = 'fail', $data = null, $code = 0): Response
    {
        return json(Tools::formatApiResult($msg, $data, $code,1));
    }
}